#include "stdafx.h"
#include "ImageIOHelper.h"
#include "ImageIOExceptions.h"

#include <windows.h>
#include "Utils.h"
#include "FileNameUtils.h"

#pragma warning(push)
#pragma warning(disable: 4996)

#pragma push_macro("FAR")
#pragma warning(push)
#pragma warning(disable: 4005)
#define XMD_H
#include <boost/gil/extension/io/jpeg_io.hpp>
#pragma warning(pop)
#pragma pop_macro("FAR")


#include "cimage_io/cimage_io.hpp"

CImageIOHelper::CImageIOHelper()
	:m_InputImageType(imtUnknown),
	 m_OutputImageType(imtUnknown),
	 m_JPEGQuality(100)
{
}

ImageType_t CImageIOHelper::GetInputImageType()
{
	return m_InputImageType;
}

void CImageIOHelper::SetOutputImageType(ImageType_t ImageType)
{
	_ASSERT( ImageType != imtUnknown );
	m_OutputImageType = ImageType;
}

void CImageIOHelper::SetJPEGQuality(int Quality)
{
	_ASSERT( (Quality >= 1) && (Quality <= 100) );
	m_JPEGQuality = Quality;
}
	
void CImageIOHelper::SaveImage(const tstring& FileName, const rgb8_image_t& Image)
{
	_ASSERT( m_OutputImageType != imtUnknown);
	switch( m_OutputImageType )
	{
	case imtJPEG: 
		SaveJPEG(FileName, Image);
		break;
	case imtPNG:
		SavePNG(FileName, Image);
		break;
	case imtGIF:
		SaveGIF(FileName, Image);
		break;
	case imtBMP:
		SaveBMP(FileName, Image);
		break;
	default:
		_ASSERT( false );
	};
}

void CImageIOHelper::LoadImage(const tstring& FileName, rgb8_image_t* Image)
{
	_ASSERT( Image != NULL);
	if( HasJPEGExt(FileName) )
	{
		m_OutputImageType = m_InputImageType = imtJPEG;
	}
	else if ( HasPNGExt(FileName) )
	{
		m_OutputImageType = m_InputImageType = imtPNG;
	}
	else if( HasGIFExt(FileName) )
	{
		m_OutputImageType = m_InputImageType = imtGIF;
	}
	else if( HasBMPExt(FileName) )
	{
		m_OutputImageType = m_InputImageType = imtBMP;
	}
	else
		throw EUnableToOpenImage();
	//
	try
	{
		cimage_read_image(FileName, *Image);
	}
	catch(std::ios_base::failure)
	{
		throw EUnableToOpenImage();
	}
}

void CImageIOHelper::SaveJPEG(const tstring& FileName, const rgb8_image_t& Image)
{
	std::string sFileName;
	if( !LPCTSTR2stdstr(FileName.c_str(), sFileName) )
		throw EUnableToOpenImage();

	try
	{
		jpeg_write_view(sFileName, const_view(Image), m_JPEGQuality);
	}
	catch(std::ios_base::failure)
	{
		throw EUnableToSaveImage();
	}
}

void CImageIOHelper::SavePNG(const tstring& FileName, const rgb8_image_t& Image)
{
	try
	{
		cimage_png_write_view(FileName, const_view(Image) );
	}
	catch(std::ios_base::failure)
	{
		throw EUnableToSaveImage();
	}
}


void CImageIOHelper::SaveGIF(const tstring& FileName, const rgb8_image_t& Image)
{
	try
	{
		cimage_gif_write_view(FileName, const_view(Image) );
	}
	catch(std::ios_base::failure)
	{
		throw EUnableToSaveImage();
	}
}

void CImageIOHelper::SaveBMP(const tstring& FileName, const rgb8_image_t& Image)
{
	try
	{
		cimage_bmp_write_view(FileName, const_view(Image) );
	}
	catch(std::ios_base::failure)
	{
		throw EUnableToSaveImage();
	}
}

#pragma warning(pop)